使用@語法糖,可以直接在函數或方法定義上方添加裝飾器,藉此表示出函式應用的附加功能
例:@dec等價於func = dec(func),這可以讓程式內容更加直觀,且具可讀性
裝飾器也是一種函式,它可以接受函式作為參數、可以把接收到的函式內部處理後再回傳一個新的值,也能再補改變函式的情況添加一些新功能
裝飾器是一種設計模式,它可以簡化函式中相同的條件判斷並重複使用,大概就是可以把已存在的函式添加額外的功能
範例:
def example_c(f):
def wrapper(*args, **kwargs):
print("Step 1")
result = f(*args, **kwargs)
print("Step 3")
return result
return wrapper
@example_c #用example_c裝飾example_a函式,相當於example_a = example_c(example_a),因此example_a被呼叫時,引用的是wrapper函式
def example_a(*args, **kwargs): #可接受任意數量的參數
print("Step 2")
return 0
# 呼叫 example_a 函數
example_a()
example_a(),因為example_a()被@example_c裝飾(包起來),因此實際上調用的函式是wrapper(*args, **kwargs),而進入wrapper函式後會先列印出Step 1,在調用並執行原本的example_a函式f(*args, **kwargs),列印Step 2,控制權回到wrapper再列印Step 3,最後wrapper函數回傳None
輸出結果:
簡單計算機實作:
def dec(f):
def wrapper(*args, **kwargs):
if kwargs.get('operation') not in ['+', '-', '*', '/']:
print('運算元有誤無法運算')
return
return f(*args, **kwargs)
return wrapper
@dec
def calculator(*args, **kwargs):
operation = kwargs.get('operation')
if operation == '+':
n = 0
for num in args:
n += num
return n
elif operation == '-':
n = 0
for num in args:
n -= num
return n
elif operation == '/':
n = args[0]
for num in args[1:]:
n /= num
return n
elif operation == '*':
n = args[0]
for num in args:
n *= num
return n
#s = +, -, *, /
print(f'連加={calculator(1, 3, 5, 7, 9, operation = '+')}, \
連減={calculator(3, 5, 7, 9, operation = '-')}, \
連乘={calculator(5, 7, 9, operation = '*')}, \
連除={calculator(100, 5, 2,operation = '/')}')
載入欲計算值後,將會先執行wrapper內的判斷式,若運算原有誤,則列印'運算元有誤',並回傳None,若符合條件則回到calculator函式,並判斷要使用何種運算方式,因為wrapper、calculater皆使用*args, **kwargs因此輸入任意數量的參數皆可運算
輸出結果:
參考資料:
https://zh.wikipedia.org/zh-tw/%E8%AF%AD%E6%B3%95%E7%B3%96
https://docs.python.org/zh-tw/3/tutorial/index.html